/*
 * User: ronma
 * Date: 09/12/2007
 *
 * Copyright (2005) IDI. All rights reserved.
 * This software is a proprietary information of Israeli Direct Insurance.
 * Created by IntelliJ IDEA.
 */
package com.idi.maven.plugins;

import org.apache.maven.plugin.MojoExecutionException;
import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
import org.codehaus.plexus.archiver.zip.ZipArchiver;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.Archiver;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import static org.codehaus.plexus.util.StringUtils.isEmpty;
import org.jfrog.jade.plugins.common.injectable.MvnInjectableSupport;

import java.io.*;
import static java.lang.String.format;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Set;
import java.text.MessageFormat;

/**
 *
 */
public class PluginUtils extends MvnInjectableSupport {
    private static final int BUFFER = 2048;

    private PluginUtils() {
    }

    /**
     * @param condition - the condition that must be met
     * @param errorMsg  - the error msg that will be thrown when condition is not met
     */
    public static void assure(boolean condition, String errorMsg) throws MojoExecutionException {
        if (!condition) {
            throw new MojoExecutionException(errorMsg);
        }
    }

    public static void extractZipFile(final File srcFile, final File destDir) throws MojoExecutionException {
        final ZipUnArchiver unArchiver = new ZipUnArchiver();
        unArchiver.enableLogging(new ConsoleLogger(Logger.LEVEL_INFO, "unArchive"));
        unArchiver.setSourceFile(srcFile);
        unArchiver.setDestDirectory(destDir);

        try {
            unArchiver.extract();
        } catch (Exception e) {
            throw new MojoExecutionException(format("failed to unarchive %s into %s", srcFile, destDir), e);
        }
    }

    public static void zipFile(File toBeArchived, File destFile) throws MojoExecutionException {
        try {
            Archiver archiver = new ZipArchiver();
            archiver.addDirectory(toBeArchived);
            archiver.setDestFile(destFile);
            archiver.createArchive();
        } catch (Exception ex) {
            throw new MojoExecutionException(format("error while trying to zip file %s into %s", toBeArchived, destFile), ex);
        }
    }

    public static File createArchive(String localArchiveZipFile, Set<File> filesToUpload) throws IOException, MojoExecutionException {
        try {
            final File localArchive = new File(localArchiveZipFile);
            //creating archive
            ZipArchiver zipArchiver = new ZipArchiver();
            zipArchiver.setDestFile(localArchive);
            for (final File file : filesToUpload) {
                zipArchiver.addFile(file, file.getName());
            }
            zipArchiver.createArchive();
            return localArchive;
        } catch (ArchiverException e) {
            throw new MojoExecutionException("Failed Archiving jars ", e);
        }
    }

    public static String getPath(final String... dirs) {
        final StringBuilder sb = new StringBuilder();
        for (final String dir : dirs) {
            if (!isEmpty(dir)) {
                sb.append(dir).append(File.separator);
            }
        }
        return sb.substring(0, sb.length() - 1);
    }

    public static String normalizedPath(final String... path) {
        String result = getPath(path);
        //1
        result = result.replace("/", File.separator);

        //
        return result;
    }

    public static File file(String... path) {
        return new File(normalizedPath(path));
    }

    public static void copyFileFromInputStream(final InputStream sourceInputStream, File destFile) throws MojoExecutionException {
        if (destFile.getParent() != null && !destFile.getParentFile().exists()) {
            destFile.getParentFile().mkdirs();
        }

        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(sourceInputStream);
            bos = new BufferedOutputStream(new FileOutputStream(destFile));
            final byte[] buf = new byte[4 * BUFFER];
            int i;
            while ((i = bis.read(buf)) != -1) {
                bos.write(buf, 0, i);
            }
        } catch (IOException ex) {
            throw new MojoExecutionException(ex.getMessage(), ex);
        } finally {
            try {
                //noinspection ConstantConditions
                if (bis != null) {
                    bis.close();
                }
                //noinspection ConstantConditions
                if (bos != null) {
                    bos.close();
                }
            } catch (Exception ex) {
                throw new MojoExecutionException(ex.getMessage(), ex);
            }
        }
    }

    /**
     * download from urlPath to targetDir/[short file name from url]
     */
    public static File downloadFromUrlToFile(final String urlPath, File targetDir) throws MojoExecutionException {
        File destFile;
        try {
            final URL url = new URL(urlPath);
            final String fileShortName = url.getFile().substring(url.getFile().lastIndexOf("/") + 1);
            InputStream sourceInputStream = url.openStream();
            destFile = new File(targetDir, fileShortName);

            copyFileFromInputStream(sourceInputStream,destFile);

        } catch (MalformedURLException e) {
            throw new MojoExecutionException(format("bad url [%s]", urlPath), e);
        }

        catch (IOException ex) {
            throw new MojoExecutionException(ex.getMessage(), ex);
        }
        return destFile;
    }

}